// 
// Decompiled by Procyon v0.5.36
// 

package com.msw.java;

import java.sql.SQLException;
import com.deepoove.poi.data.RowRenderData;
import java.sql.ResultSet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.io.FileOutputStream;

import com.deepoove.poi.NiceXWPFDocument;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.DocxRenderData;
import java.util.List;
import com.deepoove.poi.data.MiniTableRenderData;
import com.deepoove.poi.data.TextRenderData;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;

public class App {
	private static Logger log;

	static {
		App.log = Logger.getLogger(App.class);
	}

	public static void main(final String[] args) throws IOException {
		if (args.length < 4) {
			System.out.println("参数：\n" + "-h=[可选]mysql带端口地址,默认为localhost:3306\n" + "-d=数据库名称，多个数据库以英文的逗号分隔\n"
					+ "-t=[可选]表名，多个表名以英文逗号分隔，默认为全部的表\n" + "-u=用户名\n" + "-p=密码\n"
					+ "-f=[可选]文件输出目录，默认存放目录为当前目录，默认文件名为指定数据库的名称\n" + "使用问题请联系老冯");
			System.exit(0);
		}
		final Map<String, String> map = checkArgs(args);

		String dbs = map.get("-d");
		// 生成指定数据库的表结构，多个数据库以英文的逗号分隔
		String[] dbsArr = dbs.split(",");
		for (String db : dbsArr) {
			doIt(map, db);
		}

	}

	private static void doIt(final Map<String, String> map, final String currentDatabase) throws IOException {
		String outFile = map.get("-f");
		if (outFile != null && outFile.trim().length() == 0) {// 指定了存放路径
			outFile = outFile + "/数据库_" + currentDatabase + ".docx";
		} else {// 没有指定存放路径，则路径为当前路径
			outFile = "数据库_" + currentDatabase + ".docx";
		}
		log.info("存放数据库:" + currentDatabase + " 表结构的文件名为:" + outFile);

		String tableName = (String) map.get("-t");
		String sql1 = "SELECT table_name, table_type , ENGINE,table_collation,table_comment, create_options FROM information_schema.TABLES  where table_schema='"
				+ currentDatabase + "' ";

		if (tableName != null && tableName.trim().length() > 0) {
			sql1 += " and table_name in (";
			String[] tableNameArr = tableName.split(",");
			int index = 0;
			for (String tname : tableNameArr) {
				sql1 += "'" + tname + "'";
				if (index < tableNameArr.length - 1) {
					sql1 += ",";
				}
				index++;
			}
			sql1 += ")";
		}
		final String sql2 = "SELECT ordinal_position,column_name,column_type, column_key, extra ,is_nullable, column_default, column_comment,data_type,character_maximum_length FROM information_schema.columns WHERE table_schema='"
				+ currentDatabase + "' and table_name='";
		log.info("开始获取数据库对应的相关表信息...");
		final ResultSet rs = SqlUtils.getResultSet(
				SqlUtils.getConnnection((String) map.get("-h"), (String) map.get("-u"), (String) map.get("-p")), sql1);
		log.info("成功获取数据库对应的相关表信息。");
		log.info("开始组装数据表相关的元数据信息。");
		final List<Map<String, String>> list = getTableName(rs);
		final RowRenderData header = getHeader();
		final Map<String, Object> datas = new HashMap<String, Object>();
		datas.put("title", "数据库" + currentDatabase + "结构表信息");
		final List<Map<String, Object>> tableList = new ArrayList<Map<String, Object>>();
		int i = 0;
		for (final Map<String, String> str : list) {
			App.log.info((Object) str);
			++i;
			final String sql3 = String.valueOf(sql2) + str.get("table_name") + "'";
			final ResultSet set = SqlUtils.getResultSet(
					SqlUtils.getConnnection((String) map.get("-h"), (String) map.get("-u"), (String) map.get("-p")),
					sql3);
			final List<RowRenderData> rowList = getRowRenderData(set);
			final Map<String, Object> data = new HashMap<String, Object>();
			data.put("no", new StringBuilder().append(i).toString());
			data.put("table_comment", new StringBuilder(String.valueOf(str.get("table_comment"))).toString());
			data.put("engine", new StringBuilder(String.valueOf(str.get("engine"))).toString());
			data.put("table_collation", new StringBuilder(String.valueOf(str.get("table_collation"))).toString());
			data.put("table_type", new StringBuilder(String.valueOf(str.get("table_type"))).toString());
			data.put("name", new TextRenderData((String) str.get("table_name"), POITLStyle.getHeaderStyle()));
			data.put("table", new MiniTableRenderData(header, (List) rowList));
			tableList.add(data);
		}
		datas.put("tablelist", new DocxRenderData(FileUtils.Base64ToFile(outFile), (List) tableList));
		final XWPFTemplate template = XWPFTemplate.compile(FileUtils.Base64ToInputStream()).render((Map) datas);
		
		//设置页面大小「开始」
		NiceXWPFDocument docx = template.getXWPFDocument();
		CTBody body = docx.getDocument().getBody();
		if (!body.isSetSectPr()) {
		    body.addNewSectPr();
		}
		CTSectPr section = body.getSectPr();
		if(!section.isSetPgSz()) {
		    section.addNewPgSz();
		}
		// 设置页面大小  当前A4大小
		//CTPageSz pageSize = section.getPgSz();
		//pageSize.setW(BigInteger.valueOf(11907));
		//pageSize.setH(BigInteger.valueOf(16840));
		//pageSize.setOrient(STPageOrientation.PORTRAIT);
		//设置页面大小「结束」
		
		FileOutputStream out = null;
		log.info("结束组装数据表相关的元数据信息。");
		try {
			log.info("开始准备写入文件：" + outFile);
			out = new FileOutputStream(outFile);
			try {
				template.write((OutputStream) out);
				out.flush();
				log.info("写入文件成功：" + outFile);
			} catch (IOException e) {
				log.error("写入文件异常", e);
			}
		} catch (FileNotFoundException e) {
			log.error("生成文件流异常", e);
		} finally {
			try {
				out.close();
				template.close();
				App.log.info("文件:" + outFile + "操作结束");
			} catch (IOException e2) {
				log.error("关闭文件流发生异常", e2);
			}
		}
	}

	private static Map<String, String> checkArgs(final String[] args) {
		final Map<String, String> map = new HashMap<String, String>();
		for (final String str : args) {
			final String[] split = str.split("=");
			map.put(split[0], split[1]);
		}
		if (!map.containsKey("-d")) {
			App.log.info((Object) "\u8bf7\u8f93\u5165\u6570\u636e\u5e93\u540d\u79f0\uff01");
			System.exit(0);
		}
		if (!map.containsKey("-u")) {
			App.log.info((Object) "\u8bf7\u8f93\u5165\u6570\u636e\u5e93\u7528\u6237\u540d\uff01");
			System.exit(0);
		}
		if (!map.containsKey("-p")) {
			App.log.info((Object) "\u8bf7\u8f93\u5165\u6570\u636e\u5e93\u5bc6\u7801\uff01");
			System.exit(0);
		}
		return map;
	}

	private static RowRenderData getHeader() {
		final RowRenderData header = RowRenderData
				.build(new TextRenderData[] { new TextRenderData("序号", POITLStyle.getHeaderStyle()),
						new TextRenderData("字段名称", POITLStyle.getHeaderStyle()),
						new TextRenderData("字段描述", POITLStyle.getHeaderStyle()),
						new TextRenderData("字段类型", POITLStyle.getHeaderStyle()),
						new TextRenderData("长度", POITLStyle.getHeaderStyle()),
						new TextRenderData("允许空", POITLStyle.getHeaderStyle()),
						new TextRenderData("缺省值", POITLStyle.getHeaderStyle()) });
		header.setStyle(POITLStyle.getHeaderTableStyle());
		return header;
	}

	private static List<RowRenderData> getRowRenderData(final ResultSet set) {
		final List<RowRenderData> result = new ArrayList<RowRenderData>();
		try {
			int i = 0;
			while (set.next()) {
				++i;
				final RowRenderData row = RowRenderData.build(new TextRenderData[] {
						new TextRenderData(
								new StringBuilder(String.valueOf(set.getString("ordinal_position"))).toString()),
						new TextRenderData(new StringBuilder(String.valueOf(set.getString("column_name"))).toString()),
						new TextRenderData(
								new StringBuilder(String.valueOf(set.getString("column_comment"))).toString()),
						new TextRenderData(new StringBuilder(String.valueOf(set.getString("data_type"))).toString()),
						new TextRenderData(new StringBuilder(String.valueOf(set.getString("column_type"))).toString()),
						new TextRenderData(new StringBuilder(String.valueOf(set.getString("is_nullable"))).toString()),
						new TextRenderData(
								new StringBuilder(String.valueOf(set.getString("column_default"))).toString()) });
				if (i % 2 == 0) {
					row.setStyle(POITLStyle.getBodyTableStyle());
					result.add(row);
				} else {
					result.add(row);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	private static List<Map<String, String>> getTableName(final ResultSet rs) {
		final List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		try {
			while (rs.next()) {
				final Map<String, String> result = new HashMap<String, String>();
				result.put("table_name", new StringBuilder(String.valueOf(rs.getString("table_name"))).toString());
				result.put("table_type", new StringBuilder(String.valueOf(rs.getString("table_type"))).toString());
				result.put("engine", new StringBuilder(String.valueOf(rs.getString("engine"))).toString());
				result.put("table_collation",
						new StringBuilder(String.valueOf(rs.getString("table_collation"))).toString());
				result.put("table_comment",
						new StringBuilder(String.valueOf(rs.getString("table_comment"))).toString());
				result.put("create_options",
						new StringBuilder(String.valueOf(rs.getString("create_options"))).toString());
				list.add(result);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
}